<?php

namespace app\admin\controller\tongcheng;

use app\common\controller\Backend;
use think\Db;
use think\exception\DbException;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 配送模块配置
 *
 * @icon fa fa-circle-o
 */
class ModuleConfig extends Backend
{

    /**
     * ModuleConfigModel模型对象
     * @var \app\admin\model\tongcheng\ModuleConfigModel
     */
    protected $model = null;
    protected $noNeedRight = ['*'];

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\tongcheng\ModuleConfigModel;
        $this->view->assign("openTipList", $this->model->getOpenTipList());
        $this->view->assign("openPrefeeList", $this->model->getOpenPrefeeList());
        $this->view->assign("openInsureList", $this->model->getOpenInsureList());
        $this->view->assign("openRangeList", $this->model->getOpenRangeList());
        $this->view->assign("openWeightList", $this->model->getOpenWeightList());
        $this->view->assign("openSurchargeList", $this->model->getOpenSurchargeList());
        $this->view->assign("openGenderList", $this->model->getOpenGenderList());
        $this->view->assign("openCouponList", $this->model->getOpenCouponList());
        $this->view->assign("openPickupCodeList", $this->model->getOpenPickupCodeList());
        $this->view->assign("claimModeList", $this->model->getClaimModeList());
    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->with(['module'])
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit);

            foreach ($list as $row) {

                $row->getRelation('module')->visible(['name']);
            }

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 编辑
     *
     * @param $module_id
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function edit($module_id = null)
    {
        $row = $this->model->get(['module_id' => $module_id]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name     = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    /**
     * 里程配置
     */
    public function range($module_id = null)
    {
        $row = $this->model->get(['module_id' => $module_id]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }

        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        $count = count($params['range_config']);
        foreach ($params['range_config'] as $key => $config) {
            $index = $key + 1;
            // 非最后一行
            if ($index != $count) {
                if (empty($config['end']) || $config['end'] <= $config['start']) {
                    $this->error("第{$index}行距离结束值不能为空或小于等于起始值");
                }
            }
            if ($key > 0) {
                if (empty($config['fee']) || $config['fee'] <= 0) {
                    $this->error("第{$index}行费用不能为空或小于0");
                }
                if (empty($config['start']) || $config['start'] <= 0) {
                    $this->error("第{$index}行距离起始值不能为空或小于0");
                }
                if ($config['start'] < $params['range_config'][$key - 1]['end']) {
                    $this->error("第{$index}行距离起始值不能小于上一行的距离结束值");
                }
            }
        }

        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name     = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    /**
     * 重量配置
     */
    public function weight($module_id = null)
    {
        $row = $this->model->get(['module_id' => $module_id]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }

        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        // halt($params);
        $count = count($params['weight_config']);
        foreach ($params['weight_config'] as $key => $config) {
            $index = $key + 1;
            // 非最后一行
            if ($index != $count) {
                if (empty($config['end']) || $config['end'] <= $config['start']) {
                    $this->error("第{$index}行重量结束值不能为空或小于等于起始值");
                }
            }
            if ($key > 0) {
                if (empty($config['fee']) || $config['fee'] <= 0) {
                    $this->error("第{$index}行费用不能为空或小于0");
                }
                if (empty($config['start']) || $config['start'] <= 0) {
                    $this->error("第{$index}行重量起始值不能为空或小于0");
                }
                if ($config['start'] < $params['weight_config'][$key - 1]['end']) {
                    $this->error("第{$index}行重量起始值不能小于上一行的重量结束值");
                }
            }
        }

        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name     = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    /**
     * 特殊时段配置
     */
    public function surcharge($module_id = null)
    {
        $row = $this->model->get(['module_id' => $module_id]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }

        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        // halt($params);
        $params['surcharge_config'] = is_string($params['surcharge_config']) ? json_decode($params['surcharge_config'], true) : $params['surcharge_config'];
        // dd($params['surcharge_config']);
        foreach ($params['surcharge_config'] as $key => $config) {
            $index = $key + 1;
            if (empty($config['name'])) {
                $this->error("第{$index}行费用项名称不能为空");
            }
            if (empty($config['fee']) || $config['fee'] <= 0) {
                $this->error("第{$index}行费用不能为空或小于0");
            }
            if (empty($config['start'])) {
                $this->error("第{$index}行重量开始时间段不能为空");
            }
            if (empty($config['end'])) {
                $this->error("第{$index}行重量结束时间段不能为空");
            }
            if (empty($config['end'])) {
                $this->error("第{$index}行重量结束时间段不能为空");
            }

            $date       = date('Y-m-d');
            $start_time = strtotime($date . ' ' . $config['start']);
            $end_time   = strtotime($date . ' ' . $config['end']);
            if ($start_time >= $end_time) {
                $this->error("第{$index}行开始时间段不能大于等于结束时间段");
            }
            // 至少间隔30分钟
            if ($end_time - $start_time < 1800) {
                $this->error("第{$index}行开始时间段与结束时间段至少间隔30分钟");
            }
            // 重叠判断
            foreach ($params['surcharge_config'] as $k => $v) {
                if ($k == $key || !$v['status']) {
                    continue;
                }

                $i      = $k + 1;
                $s_time = strtotime($date . ' ' . $v['start']);
                $e_time = strtotime($date . ' ' . $v['end']);
                if ($start_time >= $s_time && $start_time < $e_time) {
                    $this->error("第{$index}行开始时间段与第{$i}行开始时间段重叠");
                }
                if ($end_time > $s_time && $end_time <= $e_time) {
                    $this->error("第{$index}行结束时间段与第{$i}行结束时间段重叠");
                }
            }
        }

        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name     = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    /**
     * 超时理赔配置
     */
    public function overtime($module_id = null)
    {
        $row = $this->model->get(['module_id' => $module_id]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }

        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        $params['claim_time_config']  = is_string($params['claim_time_config']) ? json_decode($params['claim_time_config'], true) : $params['claim_time_config'];
        $params['claim_peak_config']  = is_string($params['claim_peak_config']) ? json_decode($params['claim_peak_config'], true) : $params['claim_peak_config'];
        $params['claim_money_config'] = is_string($params['claim_money_config']) ? json_decode($params['claim_money_config'], true) : $params['claim_money_config'];

        // 验证预估时间规则
        $claim_time_config_count = count($params['claim_time_config']);
        foreach ($params['claim_time_config'] as $key => $config) {
            $index = $key + 1;
            if (empty($config['distance']) || $config['distance'] <= 0) {
                $this->error("第{$index}行距离不能为空或小于0");
            }
            if (empty($config['minutes']) || $config['minutes'] <= 0) {
                $this->error("第{$index}行预估分钟不能为空或小于0");
            }

            if ($key > 0) {
                if ($key != $claim_time_config_count - 1) {
                    if ($config['minutes'] <= $params['claim_time_config'][$key - 1]['minutes']) {
                        $this->error("第{$index}行分钟数不能小于上一行的分钟数");
                    }
                }
                if ($config['distance'] <= $params['claim_time_config'][$key - 1]['distance']) {
                    $this->error("第{$index}行距离不能小于上一行的距离");
                }
            }
        }

        // 验证超时理赔规则
        foreach ($params['claim_money_config'] as $key => $config) {
            $index = $key + 1;
            if (empty($config['minutes']) || $config['minutes'] <= 0) {
                $this->error("第{$index}行超时分钟不能为空或小于0");
            }
            if (empty($config['money']) || $config['money'] <= 0) {
                $this->error("第{$index}行扣费不能为空或小于0");
            }

            if ($key > 0) {
                if ($config['money'] <= $params['claim_money_config'][$key - 1]['money']) {
                    $this->error("第{$index}行扣费数不能小于上一行的扣费数");
                }
                // if ($config['money'] <= $params['claim_money_config'][$key - 1]['money']) {
                //     $this->error("第{$index}行扣费不能小于上一行的扣费");
                // }
            }
        }

        // 验证高峰时段规则
        foreach ($params['claim_peak_config'] as $key => $config) {
            $index = $key + 1;
            if (empty($config['time_range'])) {
                $this->error("第{$index}行高峰时段不能为空");
            }
            if (empty($config['minutes']) || $config['minutes'] <= 0) {
                $this->error("第{$index}行延时分钟不能为空或小于0");
            }

            $date       = date('Y-m-d');
            $start_time = strtotime($date . ' ' . $config['time_range'][0]);
            $end_time   = strtotime($date . ' ' . $config['time_range'][1]);
            if ($start_time >= $end_time) {
                $this->error("第{$index}行开始时间段不能大于等于结束时间段");
            }
            // 至少间隔30分钟
            if ($end_time - $start_time < 1800) {
                $this->error("第{$index}行开始时间段与结束时间段至少间隔30分钟");
            }
            // 重叠判断
            foreach ($params['claim_peak_config'] as $k => $v) {
                if ($k == $key) {
                    continue;
                }

                $i = $k + 1;
                if (empty($v['time_range'])) {
                    $this->error("第{$i}行高峰时段不能为空");
                }
                if (empty($v['minutes']) || $v['minutes'] <= 0) {
                    $this->error("第{$i}行延时分钟不能为空或小于0");
                }

                $s_time = strtotime($date . ' ' . $v['time_range'][0]);
                $e_time = strtotime($date . ' ' . $v['time_range'][1]);

                if ($start_time >= $s_time && $start_time < $e_time) {
                    $this->error("第{$index}行开始时间段与第{$i}行开始时间段重叠");
                }
                if ($end_time > $s_time && $end_time <= $e_time) {
                    $this->error("第{$index}行结束时间段与第{$i}行结束时间段重叠");
                }
            }
        }

        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name     = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }
}
